package com.loyal.adapter;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;

import com.loyal.impl.AdapterCallback;
import com.loyal.impl.AdapterImpl;
import com.loyal.impl.RecyclerViewItemClickListener;
import com.loyal.impl.RecyclerViewItemLongClickListener;
import com.loyal.kit.ResUtil;
import com.loyal.kit.TimeHelper;

import java.util.ArrayList;
import java.util.List;

/**
 * 适用于RecycleView
 */
public abstract class BaseRecycleAdapter<T, VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> implements AdapterImpl<T> {
    private RecyclerViewItemClickListener mOnItemClickListener;
    private RecyclerViewItemLongClickListener mOnItemLongClickListener;
    private final List<T> arrayList = new ArrayList<>();
    private AdapterCallback callback;

    public BaseRecycleAdapter() {
        this(null);
    }

    public BaseRecycleAdapter(@Nullable List<T> arrList) {
        changedList(arrList);
    }

    @Override
    public void addCallback(@Nullable AdapterCallback callback) {
        this.callback = callback;
    }

    public void callbackNotify(int what, @Nullable Object tag) {
        if (null != callback)
            callback.onCallbackNotify(what, tag);
    }

    @Override
    public void changedList(@Nullable List<T> arrList) {
        if (null == arrList)
            arrList = new ArrayList<>();
        int size = arrayList.size();
        arrayList.clear();
        notifyItemRangeRemoved(0, size);
        arrayList.addAll(arrList);
        notifyItemRangeChanged(0, arrList.size());
    }

    @Override
    public void notifyEmpty() {
        int count = getItemCount();
        arrayList.clear();
        notifyItemRangeRemoved(0, count);
        //notifyDataSetChanged();
        notifyItemRangeChanged(0, count);
    }

    @Override
    public void notifyList(@Nullable List<T> arrList) {
        changedList(arrList);
        //notifyDataSetChanged();

        int count = getItemCount();
        notifyItemRangeChanged(0, count);
    }

    public void insert(T t) {
        arrayList.add(getItemCount(), t);
        int count = getItemCount();
        notifyItemInserted(count);
    }

    /**
     * 指定位置插入
     *
     * @param position 指定位置
     * @param t        实体
     */
    public void insertAtPosition(int position, T t) {
        arrayList.add(position, t);
        notifyItemInserted(position);
    }

    /**
     * @param position 开始位置
     */
    public void insertRange(int position, @Nullable List<T> tList) {
        if (null == tList || tList.isEmpty())
            return;
        int insertSize = tList.size();
        arrayList.addAll(position, tList);
        notifyItemRangeInserted(position, insertSize);
        notifyItemRangeChanged(position, insertSize);
        Log.e("insertRange: ", "列表Size=" + getItemCount());
    }

    public void update(int position, T t) {
        arrayList.set(position, t);
        notifyItemChanged(position);
        //notifyItemRangeChanged();
    }

    public void updateRange(int position, @Nullable List<T> tList) {
        if (null == tList || tList.isEmpty())
            return;
        if (tList.size() > getItemCount())
            return;
        for (int i = 0; i < tList.size(); i++) {
            arrayList.set(i + position, tList.get(i));
        }
        notifyItemRangeChanged(position, tList.size());
    }

    public void remove(int position) {
        if (isEmpty())
            return;
        if (position > getItemCount() - 1)
            return;
        arrayList.remove(position);
        notifyItemRemoved(position);
    }

    /**
     * @param positionStart 要删除的起始位置
     * @param count         删除的数量
     */
    public void removeRange(int positionStart, int count) {
        if (isEmpty())
            return;
        try {
            List<T> subList = arrayList.subList(positionStart, positionStart + count);
            arrayList.removeAll(subList);
            notifyItemRangeRemoved(positionStart, count);
            //notifyDataSetChanged();
            //受影响的item都刷新position
            //notifyItemRangeChanged(positionStart, getItemCount() - 1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public boolean isEmpty() {
        return 0 == getItemCount();
    }

    @NonNull
    @Override
    public List<T> getList() {
        return arrayList;
    }

    @Override
    public View getConvertView(ViewGroup parent) {
        Context mContext = parent.getContext();
        LayoutInflater inflater = LayoutInflater.from(mContext);
        return inflater.inflate(adapterLayout(), parent, false);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public T getItem(int position) {
        return arrayList.get(position);
    }

    @Override
    public int getItemCount() {
        return arrayList.size();
    }

    public void setOnItemClickListener(RecyclerViewItemClickListener itemClickListener) {
        this.mOnItemClickListener = itemClickListener;
    }

    public boolean setOnItemLongClickListener(RecyclerViewItemLongClickListener listener) {
        this.mOnItemLongClickListener = listener;
        return false;
    }

    public abstract VH createViewHolder(View view);

    @NonNull
    @Override
    public VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return createViewHolder(getConvertView(parent));
    }

    public abstract void onViewHolder(@NonNull VH holder, int position);

    @Override
    public void onBindViewHolder(@NonNull VH holder, int position) {
        onViewHolder(holder, position);
        long itemId = holder.getItemId();
        holder.itemView.setOnClickListener(v -> {
            if (null != mOnItemClickListener) {
                mOnItemClickListener.onItemClick(this, v, position, itemId);
            }
        });
        holder.itemView.setOnLongClickListener(v -> {
            if (null != mOnItemLongClickListener) {
                return mOnItemLongClickListener.onItemLongClick(this, v, position, itemId);
            }
            return false;
        });
    }

    @NonNull
    @Override
    public String replaceText(CharSequence sequence) {
        return ResUtil.replaceText(sequence);
    }

    @NonNull
    @Override
    public String subEndTime(CharSequence sequence) {
        return TimeHelper.subEndTime(sequence);
    }
}